package cn.alm.miniodemo.controller;

import cn.alm.miniodemo.common.CommonResult;
import cn.alm.miniodemo.entity.Bucket;
import cn.alm.miniodemo.entity.MinioObject;
import cn.alm.miniodemo.service.MinioService;
import io.minio.*;
import io.minio.errors.*;
import io.minio.messages.Item;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.simpleframework.xml.Path;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.UUID;

@RestController
@CrossOrigin
@Slf4j
public class MinioController {

    @Resource
    private MinioService minioService;

    @Value("${minio.bucket.name}")
    private String minioBucketName;

    @Resource
    private MinioClient minioClient;

    @PostMapping("minio/listBucketContent")
    public CommonResult listBucketContent(@RequestBody Bucket bucket) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        String name = bucket.getName();
        Iterable<Result<Item>> results = minioClient.listObjects(ListObjectsArgs.builder().bucket(name).build());
        Iterator<Result<Item>> iterator = results.iterator();
        ArrayList<Object> items = new ArrayList<>();
        String format = "{'fileName':'%s','fileSize':'%s'}";
        while (iterator.hasNext()) {
            Item item = iterator.next().get();
            String objectName = item.objectName();
            long size = item.size();
            HashMap<String, Object> map = new HashMap<>();
            map.put("name", objectName);
            map.put("size", size);
            items.add(map);
        }
        CommonResult cr = new CommonResult();
        cr.setCode("200");
        cr.setSuccess(true);
        cr.setMessage("请求成功");
        cr.setData(items);
        return cr;
    }

    @GetMapping("minio/download/{bucketName}/{fileName}")
    public void download(HttpServletResponse response, @PathVariable("bucketName") String bucketName, @PathVariable("fileName") String fileName) {
        InputStream in = null;
        try {
            StatObjectResponse stat = minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(fileName).build());
            response.setContentType(stat.contentType());
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            in = minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(fileName).build());
            IOUtils.copy(in, response.getOutputStream());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }
    }

    @PostMapping("minio/deleteObject")
    public CommonResult deleteObject(@RequestBody MinioObject object) {
        String bucketName = object.getBucketName();
        String name = object.getName();
        CommonResult cr = new CommonResult();
        try {
            minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(name).build());
            cr.setCode("200");
            cr.setSuccess(true);
            cr.setMessage("删除成功！");
        } catch (Exception e) {
            e.printStackTrace();
            cr.setCode("500");
            cr.setSuccess(false);
            cr.setMessage("删除失败！");
        }
        return cr;
    }

    @PostMapping("minio/upload")
    public CommonResult upload(@RequestParam(name = "file", required = false) MultipartFile file) {
        String upload = minioService.upload(file);
        CommonResult cr = new CommonResult();
        cr.setCode("200");
        cr.setSuccess(true);
        cr.setMessage("上传成功！");
        cr.setData(upload);
        return cr;
    }

}
